package cn.echo.consul.manager.interceptor;

import cn.echo.consul.manager.annotation.RequestPermissions;
import cn.echo.consul.manager.enums.PermissionRole;
import cn.echo.consul.manager.exception.ForbiddenException;
import cn.echo.consul.manager.service.ProjectInfoService;
import cn.echo.consul.manager.service.UserInfoService;
import lombok.RequiredArgsConstructor;
import org.springframework.util.StringUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Arrays;
import java.util.List;

import static cn.echo.consul.manager.constant.HeaderFields.AUTH_USER_ID;

/**
 * 页面访问权限拦截
 * @author lonyee
 */
@RequiredArgsConstructor
public class PermissionInterceptor extends HandlerInterceptorAdapter {

    final UserInfoService userInfoService;
    final ProjectInfoService projectInfoService;

    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }
        //处理Permission Annotation，实现方法级权限控制
        HandlerMethod method = (HandlerMethod)handler;
        RequestPermissions permission = method.getMethodAnnotation(RequestPermissions.class);
        if (permission == null) {
            //如果为空在表示该方法不需要进行权限验证
            return true;
        }

        String userId = request.getAttribute(AUTH_USER_ID) +"";
        if (StringUtils.isEmpty(userId)) {
            throw new ForbiddenException();
        }
        List<PermissionRole> codes = Arrays.asList(permission.value());
        if (codes.contains(PermissionRole.ADMIN)) {
            boolean isAdmin = userInfoService.getUserIsAdmin(userId);
            if (isAdmin) {
                return true;
            }
        }
        String projectId = request.getParameter("projectId");
        if (!StringUtils.isEmpty(projectId)) {
            PermissionRole role = projectInfoService.getUserPermission(userId, projectId);
            if (role!=null && codes.contains(role)) {
                return true;
            }
        }
        throw new ForbiddenException();
    }

}
